import sys
import os # os 需要先导入

# 确保路径设置在尝试导入模块之前
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# --- 从 main 导入 resource_path --- 
# try:
#     from main import resource_path
# except ImportError as e:
#     print(f"Error importing resource_path from main: {e}")
#     # Fallback
#     def resource_path(relative_path):
#         print("Warning: Using fallback resource_path in main_window. Packaging might fail.")
#         # Assume main_window.py is in ui/, resources/ is sibling to ui/
#         base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
#         return os.path.join(base_path, relative_path)
# --------------------------------

# --- 改为从 utils 导入 resource_path ---
from utils import resource_path
# -------------------------------------

from PyQt6.QtWidgets import (
    QMainWindow, QApplication, QWidget, QVBoxLayout, QHBoxLayout, 
    QLabel, QPushButton, QListWidget, QDateTimeEdit, QLineEdit, 
    QMessageBox, QListWidgetItem, QSystemTrayIcon, QMenu, 
    QComboBox, QMenuBar, QFileDialog, QGroupBox # GroupBox 移到这里
)
from PyQt6.QtCore import Qt, QDateTime, QTimer, pyqtSlot, QPoint # 添加 pyqtSlot 和 QPoint
from PyQt6.QtGui import QIcon, QAction

# 导入核心逻辑和对话框
from core.alarm_manager import AlarmManager, Alarm, datetime, DEFAULT_REPEAT_RULE_DISPLAY, DEFAULT_CATEGORY # 导入常量
from ui.category_dialog import CategoryDialog # 导入分类对话框

# 导入用于自启动和窗口激活的库
import sys
try:
    import winshell
    from win32com.client import Dispatch # 需要 pywin32，通常随 winshell 一起安装
    import win32gui
    import win32con
except ImportError:
    winshell = None
    win32gui = None
    win32con = None
    print("警告: 未找到 winshell 或 pywin32 库，无法支持开机自启设置或强制窗口激活。请运行 'pip install winshell pywin32' 安装。")

# --- 基本 QSS 样式表 ---
# 一个简单的深色主题示例
QSS = """
QMainWindow {
    background-color: #2E2E2E;
}
QWidget#central_widget { /* 为 central widget 指定 objectName 以应用特定样式 */
    background-color: #3C3C3C;
}
QLabel {
    color: #E0E0E0;
    font-size: 10pt;
}
QLineEdit, QDateTimeEdit {
    background-color: #505050;
    color: #F0F0F0;
    border: 1px solid #6E6E6E;
    border-radius: 4px;
    padding: 5px;
    font-size: 10pt;
}
QLineEdit:focus, QDateTimeEdit:focus {
    border: 1px solid #4A90E2;
}
QPushButton {
    background-color: #4A90E2; /* 蓝色按钮 */
    color: white;
    border: none;
    padding: 8px 16px;
    border-radius: 4px;
    font-size: 10pt;
}
QPushButton:hover {
    background-color: #357ABD;
}
QPushButton:pressed {
    background-color: #2A65A0;
}
/* 过滤按钮特殊样式 */
QPushButton[checkable="true"] {
    background-color: #505050;
    color: #E0E0E0;
    border: 1px solid #6E6E6E;
}
QPushButton[checkable="true"]:checked {
    background-color: #4A90E2;
    color: white;
    border: 1px solid #357ABD;
}
QPushButton[checkable="true"]:hover {
    background-color: #5A5A5A;
}
QPushButton[checkable="true"]:checked:hover {
    background-color: #357ABD;
}
QListWidget {
    background-color: #505050;
    color: #E0E0E0;
    border: 1px solid #6E6E6E;
    border-radius: 4px;
    font-size: 10pt;
    alternate-background-color: #5A5A5A; /* 交替行颜色 */
}
QListWidget::item {
    padding: 5px;
}
QListWidget::item:selected {
    background-color: #4A90E2; /* 选中项背景色 */
    color: white;
}
/* 为禁用的控件设置样式 */
QComboBox:disabled, QLineEdit:disabled, QDateTimeEdit:disabled {
    background-color: #454545;
    color: #888888;
}
QComboBox {
     background-color: #505050;
     color: #F0F0F0;
     border: 1px solid #6E6E6E;
     border-radius: 4px;
     padding: 3px 5px;
}
QComboBox QAbstractItemView { /* 下拉列表样式 */
    background-color: #505050;
    color: #F0F0F0;
    border: 1px solid #6E6E6E;
    selection-background-color: #4A90E2;
}
QMenuBar {
    background-color: #2E2E2E;
    color: #E0E0E0;
}
QMenuBar::item {
    background-color: transparent;
    padding: 4px 8px;
}
QMenuBar::item:selected {
    background-color: #4A90E2;
    color: white;
}
QMenu {
    background-color: #3C3C3C;
    color: #E0E0E0;
    border: 1px solid #6E6E6E;
}
QMenu::item {
    padding: 5px 20px;
}
QMenu::item:selected {
    background-color: #4A90E2;
    color: white;
}
QMenu::separator {
    height: 1px;
    background-color: #6E6E6E;
    margin-left: 5px;
    margin-right: 5px;
}
QMessageBox {
     background-color: #3C3C3C;
}
QMessageBox QLabel {
      color: #E0E0E0; 
      min-width: 250px; /* 防止文本太窄 */
}
QMessageBox QPushButton {
      min-width: 60px; /* 消息框按钮宽度 */
}

"""

# 应用名称，用于快捷方式
APP_NAME = "桌面闹钟"

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("桌面闹钟")
        # --- 使用 resource_path 获取图标路径 --- 
        try:
             icon_path = resource_path(os.path.join('resources', 'icons', 'icon2.png'))
             self.app_icon = QIcon(icon_path)
             if not os.path.exists(icon_path):
                  print(f"警告: 图标文件未找到: {icon_path}")
                  self.app_icon = QIcon() # 使用空图标
        except Exception as e:
             print(f"加载图标时出错: {e}")
             self.app_icon = QIcon() # 出错时使用空图标
             
        self.setWindowIcon(self.app_icon)
        # --------------------------------------
        self.setGeometry(100, 100, 800, 600) # 稍微增大窗口 accommodating 新控件

        # 初始化 AlarmManager
        self.alarm_manager = AlarmManager()
        self.alarm_manager.alarms_changed.connect(self.update_alarm_list)
        self.alarm_manager.alarm_triggered.connect(self.show_alarm_popup)
        self.alarm_manager.categories_changed.connect(self.update_categories_ui) # 连接分类变化信号

        # 获取快捷方式路径
        self.startup_folder = winshell.startup() if winshell else None
        self.shortcut_path = os.path.join(self.startup_folder, f"{APP_NAME}.lnk") if self.startup_folder else None

        # 用于跟踪正在编辑的闹钟ID
        self.editing_alarm_id = None
        
        # 闹钟过滤状态：'enabled'(仅启用), 'disabled'(仅禁用), 'all'(全部)
        self.alarm_filter = 'enabled'

        self.init_menu() # 初始化菜单栏
        self.init_ui()   # 初始化主界面
        self.init_tray_icon() # 初始化系统托盘图标
        self.update_alarm_list() # 初始加载时更新列表
        self.update_categories_ui() # 初始化时加载分类到下拉框
        
        # 应用样式表
        self.apply_stylesheet()

    def apply_stylesheet(self):
        """应用 QSS 样式表"""
        self.setStyleSheet(QSS)
        # 确保 central widget 有 objectName 以便应用特定样式
        self.centralWidget().setObjectName("central_widget") 

    def init_menu(self):
        """初始化菜单栏"""
        menu_bar = self.menuBar() # 获取菜单栏

        # --- 文件菜单 ---
        file_menu = menu_bar.addMenu("&文件")

        import_action = QAction(QIcon(), "&导入闹钟...", self) # TODO: 添加图标
        import_action.triggered.connect(self.import_alarms) # 连接到占位符方法
        file_menu.addAction(import_action)

        export_action = QAction(QIcon(), "&导出闹钟...", self) # TODO: 添加图标
        export_action.triggered.connect(self.export_alarms) # 连接到占位符方法
        file_menu.addAction(export_action)

        file_menu.addSeparator()

        # 将退出动作也放入文件菜单 (可选, 托盘已有)
        quit_action = QAction(QIcon(), "&退出", self) # TODO: 添加图标
        quit_action.triggered.connect(self.quit_application)
        file_menu.addAction(quit_action)

        # --- 编辑/设置菜单 (占位) ---
        edit_menu = menu_bar.addMenu("&设置")
        manage_categories_action = QAction("管理分类...", self)
        manage_categories_action.setEnabled(True) # 启用菜单项
        manage_categories_action.triggered.connect(self.open_category_dialog) # 连接到打开对话框的方法
        edit_menu.addAction(manage_categories_action)

    def init_ui(self):
        central_widget = QWidget(self)
        self.setCentralWidget(central_widget)

        main_layout = QVBoxLayout(central_widget)

        # --- 闹钟列表 ---
        list_layout = QVBoxLayout()
        
        # 添加过滤控件
        filter_layout = QHBoxLayout()
        self.filter_label = QLabel("显示闹钟:")
        filter_layout.addWidget(self.filter_label)
        
        # 过滤按钮组
        self.filter_enabled_btn = QPushButton("仅启用")
        self.filter_enabled_btn.setCheckable(True)
        self.filter_enabled_btn.setChecked(True)  # 默认选中
        self.filter_enabled_btn.clicked.connect(lambda: self.set_alarm_filter('enabled'))
        filter_layout.addWidget(self.filter_enabled_btn)
        
        self.filter_disabled_btn = QPushButton("仅禁用")
        self.filter_disabled_btn.setCheckable(True)
        self.filter_disabled_btn.clicked.connect(lambda: self.set_alarm_filter('disabled'))
        filter_layout.addWidget(self.filter_disabled_btn)
        
        self.filter_all_btn = QPushButton("全部")
        self.filter_all_btn.setCheckable(True)
        self.filter_all_btn.clicked.connect(lambda: self.set_alarm_filter('all'))
        filter_layout.addWidget(self.filter_all_btn)
        
        filter_layout.addStretch(1)  # 添加弹性空间
        list_layout.addLayout(filter_layout)
        
        # 动态标签，根据过滤状态显示不同提示
        self.list_info_label = QLabel("启用的闹钟 (双击禁用, 右键修改):")
        list_layout.addWidget(self.list_info_label)
        
        self.alarm_list_widget = QListWidget()
        self.alarm_list_widget.itemDoubleClicked.connect(self.toggle_alarm_enabled)
        self.alarm_list_widget.setAlternatingRowColors(True)
        # --- 启用自定义右键菜单 ---
        self.alarm_list_widget.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.alarm_list_widget.customContextMenuRequested.connect(self.show_alarm_context_menu)
        # ------------------------
        # --- 点击列表项时重置编辑状态 (可选, 简化交互) ---
        self.alarm_list_widget.currentItemChanged.connect(self.reset_edit_state_if_needed)
        # ------------------------------------------
        list_layout.addWidget(self.alarm_list_widget)
        main_layout.addLayout(list_layout, 3)

        # --- 添加/编辑 区域 ---
        # 修改 GroupBox 标题以反映编辑状态
        self.add_edit_groupbox = QGroupBox("添加闹钟")
        add_alarm_group_layout = QVBoxLayout(self.add_edit_groupbox)

        # 时间和事项行
        time_msg_layout = QHBoxLayout()
        time_msg_layout.addWidget(QLabel("时间:"))
        self.datetime_edit = QDateTimeEdit(QDateTime.currentDateTime().addSecs(60)) # 默认1分钟后
        self.datetime_edit.setCalendarPopup(True)
        self.datetime_edit.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
        time_msg_layout.addWidget(self.datetime_edit, 1)
        time_msg_layout.addWidget(QLabel("事项:"))
        self.message_edit = QLineEdit()
        self.message_edit.setPlaceholderText("输入提醒事项...")
        time_msg_layout.addWidget(self.message_edit, 2)
        add_alarm_group_layout.addLayout(time_msg_layout)

        # 重复和分类行
        repeat_cat_layout = QHBoxLayout()
        repeat_cat_layout.addWidget(QLabel("重复:"))
        self.repeat_combo = QComboBox()
        self.repeat_combo.addItems([DEFAULT_REPEAT_RULE_DISPLAY, "每天", "每周", "每月"]) # 修改：移除 "每年" 选项
        repeat_cat_layout.addWidget(self.repeat_combo)
        repeat_cat_layout.addWidget(QLabel("分类:"))
        self.category_combo = QComboBox() # 分类内容将由 update_categories_ui 填充
        repeat_cat_layout.addWidget(self.category_combo)
        repeat_cat_layout.addStretch(1)
        add_alarm_group_layout.addLayout(repeat_cat_layout)
        
        # 按钮行
        button_layout = QHBoxLayout(); button_layout.addStretch(1)
        # --- 修改按钮名称和连接 ---
        self.save_button = QPushButton("添加闹钟") # 初始文本
        self.save_button.clicked.connect(self.save_or_update_alarm) # 连接到新的处理函数
        button_layout.addWidget(self.save_button)
        # --- 添加取消编辑按钮 ---
        self.cancel_button = QPushButton("取消编辑")
        self.cancel_button.clicked.connect(self.reset_edit_state)
        self.cancel_button.setVisible(False) # 初始隐藏
        button_layout.addWidget(self.cancel_button)
        # ----------------------
        self.remove_button = QPushButton("删除选中"); self.remove_button.clicked.connect(self.remove_selected_alarm)
        button_layout.addWidget(self.remove_button)
        add_alarm_group_layout.addLayout(button_layout)

        main_layout.addWidget(self.add_edit_groupbox) # 使用新的 groupbox 变量
        main_layout.setStretchFactor(list_layout, 3)
        main_layout.setStretchFactor(self.add_edit_groupbox, 1)

    def init_tray_icon(self):
        """初始化系统托盘图标及其菜单"""
        self.tray_icon = QSystemTrayIcon(self.app_icon, self)
        self.tray_icon.setToolTip("桌面闹钟")

        # 创建托盘菜单
        tray_menu = QMenu(self)

        # 显示/隐藏 动作
        show_hide_action = QAction("显示/隐藏窗口", self)
        show_hide_action.triggered.connect(self.toggle_window_visibility)
        tray_menu.addAction(show_hide_action)

        # --- 添加开机自启选项 --- 
        if winshell:
            self.autostart_action = QAction("开机自启", self)
            self.autostart_action.setCheckable(True)
            self.autostart_action.setChecked(self.is_autostart_enabled()) # 设置初始状态
            self.autostart_action.triggered.connect(self.toggle_autostart)
            tray_menu.addAction(self.autostart_action)
        # --- 结束添加 --- 

        tray_menu.addSeparator()

        # 退出 动作
        quit_action = QAction("退出", self)
        quit_action.triggered.connect(self.quit_application) # 连接到真正的退出方法
        tray_menu.addAction(quit_action)

        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.activated.connect(self.on_tray_icon_activated)
        self.tray_icon.show()

    def on_tray_icon_activated(self, reason):
        """处理托盘图标激活事件 (例如左键单击)"""
        # 左键单击时切换窗口可见性
        if reason == QSystemTrayIcon.ActivationReason.Trigger:
            self.toggle_window_visibility()

    def toggle_window_visibility(self):
        """切换主窗口的可见性"""
        if self.isVisible():
            self.hide()
        else:
            self.show()
            self.activate_window()

    def activate_window(self):
        """将窗口带到前台并激活"""
        # --- 简化：移除 WinAPI 调用，主要使用 Qt 方法 ---
        # 确保窗口可见
        if not self.isVisible():
            self.show()
            print(f"Called self.show() in activate_window")

        # 如果窗口最小化，则恢复
        if self.isMinimized():
            self.showNormal()
            print(f"Called self.showNormal() in activate_window")

        # 提升窗口到顶层
        self.raise_()
        # 激活窗口
        self.activateWindow()
        print(f"Called Qt raise_() and activateWindow() in activate_window")
        # -------------------------------------------------

    def closeEvent(self, event):
        """重写关闭事件，实现隐藏到托盘而不是退出"""
        event.ignore() # 忽略默认的关闭事件 (退出)
        self.hide()    # 隐藏窗口
        self.tray_icon.showMessage(
            "桌面闹钟",
            "应用已最小化到托盘。",
            self.app_icon, # 使用存储的图标
            2000 # 消息显示时间 (毫秒)
        )

    def quit_application(self):
        """完全退出应用程序"""
        # 清理资源，例如停止定时器 (虽然 Python 的垃圾回收通常会处理)
        # self.alarm_manager._check_timer.stop() # 可以选择显式停止
        self.tray_icon.hide() # 隐藏托盘图标
        QApplication.quit() # 退出应用事件循环

    def set_alarm_filter(self, filter_type):
        """设置闹钟过滤类型并更新界面"""
        self.alarm_filter = filter_type
        
        # 更新按钮状态 - 只有当前选中的按钮保持选中状态
        self.filter_enabled_btn.setChecked(filter_type == 'enabled')
        self.filter_disabled_btn.setChecked(filter_type == 'disabled')
        self.filter_all_btn.setChecked(filter_type == 'all')
        
        # 更新标签文本
        if filter_type == 'enabled':
            self.list_info_label.setText("启用的闹钟 (双击禁用, 右键修改):")
        elif filter_type == 'disabled':
            self.list_info_label.setText("禁用的闹钟 (双击启用, 右键修改):")
        else:  # 'all'
            self.list_info_label.setText("所有闹钟 (双击切换状态, 右键修改):")
        
        # 刷新闹钟列表
        self.update_alarm_list()

    def update_alarm_list(self):
        """根据当前过滤设置刷新界面上的闹钟列表"""
        # 当列表更新时，如果正在编辑的闹钟被删除了，需要重置状态
        if self.editing_alarm_id and not self.alarm_manager.get_alarm(self.editing_alarm_id):
            print(f"正在编辑的闹钟 {self.editing_alarm_id} 已不存在，重置编辑状态。")
            self.reset_edit_state()
            
        current_selection_id = None
        if self.alarm_list_widget.currentItem():
            current_selection_id = self.alarm_list_widget.currentItem().data(Qt.ItemDataRole.UserRole)
            
        self.alarm_list_widget.clear()
        all_alarms = self.alarm_manager.get_all_alarms()
        
        # 根据过滤设置筛选闹钟
        if self.alarm_filter == 'enabled':
            filtered_alarms = [alarm for alarm in all_alarms if alarm.enabled]
        elif self.alarm_filter == 'disabled':
            filtered_alarms = [alarm for alarm in all_alarms if not alarm.enabled]
        else:  # 'all'
            filtered_alarms = all_alarms
        
        item_to_reselect = None
        for alarm in filtered_alarms:
            item = QListWidgetItem(str(alarm))
            item.setData(Qt.ItemDataRole.UserRole, alarm.id)
            # 如果显示全部闹钟，给禁用的闹钟添加删除线样式
            if self.alarm_filter == 'all' and not alarm.enabled:
                font = item.font()
                font.setStrikeOut(True)
                item.setFont(font)
            self.alarm_list_widget.addItem(item)
            if alarm.id == current_selection_id: # 尝试恢复之前的选中项
                item_to_reselect = item
                
        if item_to_reselect:
            self.alarm_list_widget.setCurrentItem(item_to_reselect)

    def add_new_alarm(self):
        """处理添加新闹钟按钮点击事件"""
        alarm_time_qdt = self.datetime_edit.dateTime()
        alarm_time_dt = alarm_time_qdt.toPyDateTime() # 使用 toPyDateTime 转换
        message = self.message_edit.text().strip()
        repeat_rule = self.repeat_combo.currentText()
        category = self.category_combo.currentText() # 直接获取当前选中的分类

        if not message:
            QMessageBox.warning(self, "提醒", "请输入提醒事项内容。")
            return
            
        if not alarm_time_dt:
            QMessageBox.warning(self, "提醒", "无效的时间设置。")
            return

        if alarm_time_dt <= datetime.now():
             QMessageBox.warning(self, "提醒", "时间必须晚于当前。")
             return

        new_alarm = Alarm(alarm_time=alarm_time_dt, message=message)
        new_alarm.repeat_rule = repeat_rule if repeat_rule != DEFAULT_REPEAT_RULE_DISPLAY else None
        new_alarm.category = category if category != "默认" else None
        self.alarm_manager.add_alarm(new_alarm)
        
        # 清空输入框并重置时间 (例如设置为当前时间+1分钟)
        self.message_edit.clear()
        self.datetime_edit.setDateTime(QDateTime.currentDateTime().addSecs(60))
        repeat_index = self.repeat_combo.findText(DEFAULT_REPEAT_RULE_DISPLAY)
        if repeat_index != -1: self.repeat_combo.setCurrentIndex(repeat_index)
        default_cat_index = self.category_combo.findText("默认")
        if default_cat_index != -1: self.category_combo.setCurrentIndex(default_cat_index) # 重置为 "默认"

        # update_alarm_list 会通过 alarms_changed 信号自动调用

    def remove_selected_alarm(self):
        """删除选中的闹钟"""
        selected_items = self.alarm_list_widget.selectedItems()
        if not selected_items:
            QMessageBox.information(self, "提醒", "请先在列表中选择要删除的闹钟。")
            return

        reply = QMessageBox.question(self, "确认删除", 
                                     f"确定要删除选中的 {len(selected_items)} 个闹钟吗?",
                                     QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                                     QMessageBox.StandardButton.No)

        if reply == QMessageBox.StandardButton.Yes:
            for item in selected_items:
                alarm_id = item.data(Qt.ItemDataRole.UserRole)
                if alarm_id:
                    # 如果正在编辑的闹钟被删除，先重置状态
                    if alarm_id == self.editing_alarm_id:
                        self.reset_edit_state()
                    self.alarm_manager.remove_alarm(alarm_id)
            # 列表会自动更新，因为 remove_alarm 会发信号

    def toggle_alarm_enabled(self, item: QListWidgetItem):
        """双击列表项时，切换闹钟的启用/禁用状态"""
        alarm_id = item.data(Qt.ItemDataRole.UserRole)
        if not alarm_id:
            return
            
        alarm = self.alarm_manager.get_alarm(alarm_id)
        if alarm:
            alarm.enabled = not alarm.enabled
            self.alarm_manager.update_alarm(alarm) 
            # update_alarm_list 会自动调用

    def show_alarm_popup(self, alarm: Alarm):
        """显示闹钟触发的弹窗"""
        self.activateWindow() # 尝试激活主窗口
        
        # --- 修改：只显示提醒内容，黄色，更大字号 --- 
        title = "闹钟提醒!"
        # 直接使用提醒事项作为主要内容，设置样式
        message_html = f"""
        <p style='font-size: 16pt; color: yellow;'>{alarm.message}</p>
        """
        
        QTimer.singleShot(0, lambda: QMessageBox.information(self, \
                                title, \
                                message_html, \
                                QMessageBox.StandardButton.Ok))
        # ----------------------------------------------

    def get_executable_path(self):
        """获取当前运行的脚本或可执行文件的路径"""
        if getattr(sys, 'frozen', False):
            # 如果是打包后的 exe (PyInstaller)
            return sys.executable
        else:
            # 如果是直接运行 .py 脚本
            # 注意：这会创建对 python.exe 的快捷方式，并传递脚本路径作为参数
            # 这可能不是所有情况下都理想，但对于基本功能是可行的
            # return sys.executable # 指向 python.exe
            # 或者直接返回脚本路径？ 但需要 python 解释器来运行
            # 返回主脚本的路径，快捷方式的目标需要设置为 python.exe，参数为这个路径
            return os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'main.py'))
            
    def get_python_executable(self):
         """获取 Python 解释器路径"""
         return sys.executable

    def is_autostart_enabled(self) -> bool:
        """检查自启动快捷方式是否存在"""
        if not self.shortcut_path:
            return False
        return os.path.exists(self.shortcut_path)

    def toggle_autostart(self):
        """切换开机自启状态"""
        if not winshell or not self.shortcut_path:
            QMessageBox.warning(self, "错误", "无法设置开机自启，缺少必要的库 (winshell, pywin32)。")
            # 取消勾选状态
            if hasattr(self, 'autostart_action'): self.autostart_action.setChecked(False)
            return

        try:
            if self.is_autostart_enabled():
                # --- 删除快捷方式 ---
                os.remove(self.shortcut_path)
                print(f"已禁用开机自启 (删除快捷方式: {self.shortcut_path})")
                self.autostart_action.setChecked(False)
            else:
                # --- 创建快捷方式 ---
                target = self.get_executable_path()
                working_dir = os.path.dirname(target)
                icon_loc = self.app_icon.name() # 获取图标路径
                
                # 如果是 .py 文件，目标应该是 Python 解释器，参数是脚本路径
                if target.endswith('.py'):
                    script_path = target
                    target = self.get_python_executable()
                    args = f'"{script_path}"' # 参数需要引号包围以处理空格
                    working_dir = os.path.dirname(script_path)
                else:
                    args = '' # 打包后的 exe 通常不需要额外参数

                shell = Dispatch('WScript.Shell')
                shortcut = shell.CreateShortCut(self.shortcut_path)
                shortcut.Targetpath = target
                shortcut.Arguments = args
                shortcut.WorkingDirectory = working_dir
                if os.path.exists(icon_loc):
                     shortcut.IconLocation = icon_loc
                shortcut.WindowStyle = 1 # 1: Normal, 7: Minimized
                shortcut.save()
                print(f"已启用开机自启 (创建快捷方式: {self.shortcut_path} 指向 {target} 参数 {args})")
                self.autostart_action.setChecked(True)

        except Exception as e:
            print(f"设置开机自启时出错: {e}")
            QMessageBox.critical(self, "错误", f"设置开机自启失败: {e}")
            # 回滚勾选状态
            if hasattr(self, 'autostart_action'): 
                 self.autostart_action.setChecked(self.is_autostart_enabled()) 

    # --- 分类管理 --- 
    @pyqtSlot()
    def open_category_dialog(self):
        """打开分类管理对话框"""
        dialog = CategoryDialog(self.alarm_manager, self)
        # 如果对话框修改了分类，AlarmManager 会发出 categories_changed 信号
        # MainWindow 已经连接了这个信号到 update_categories_ui
        dialog.exec() # 以模态方式显示对话框
        
    @pyqtSlot(list)
    def update_categories_ui(self, categories=None):
        """更新分类下拉框的内容"""
        if categories is None:
            categories = self.alarm_manager.get_categories()
            
        current_selection = self.category_combo.currentText()
        self.category_combo.clear()
        self.category_combo.addItems(categories)
        
        # 尝试恢复之前的选择
        index = self.category_combo.findText(current_selection)
        if index != -1:
            self.category_combo.setCurrentIndex(index)
        else:
             # 修改：回退到常量 DEFAULT_CATEGORY ("工作")
             default_index = self.category_combo.findText(DEFAULT_CATEGORY)
             if default_index != -1:
                  self.category_combo.setCurrentIndex(default_index)
             # 如果连默认分类都找不到（理论上不该发生），则选择第一个
             elif self.category_combo.count() > 0:
                  self.category_combo.setCurrentIndex(0)

    # --- 文件导入/导出方法 (占位) ---
    def import_alarms(self):
        """处理文件菜单中的导入动作"""
        # --- 实现导入逻辑 --- 
        filepath, _ = QFileDialog.getOpenFileName(
            self,
            "导入闹钟文件",
            "", # 默认目录 (可设为用户文档目录等)
            "JSON 文件 (*.json);;所有文件 (*.*)"
        )

        if filepath: # 用户选择了文件
            print(f"准备从文件导入闹钟: {filepath}")
            try:
                # 调用 AlarmManager 的导入方法 (稍后实现)
                imported_count = self.alarm_manager.import_alarms_from_json(filepath)
                if imported_count is not None: # 假设返回 int 或 None
                    QMessageBox.information(self, "导入完成", f"成功导入 {imported_count} 个闹钟。")
                    # 导入后无需手动刷新，因为 AlarmManager 的 add_alarm 会触发信号
                else:
                    QMessageBox.warning(self, "导入失败", "导入过程中发生错误，请检查文件格式或查看日志。")
            except FileNotFoundError:
                 QMessageBox.critical(self, "错误", f"文件未找到: {filepath}")
            except Exception as e:
                 print(f"导入闹钟时发生未知错误: {e}")
                 QMessageBox.critical(self, "导入错误", f"导入时发生未知错误: {e}")
        else:
             print("用户取消了导入操作。")
        # -------------------------
        # QMessageBox.information(self, "提示", "导入功能尚未实现。") # <-- 旧的占位符

    def export_alarms(self):
        """处理文件菜单中的导出动作"""
        # --- 实现导出逻辑 --- 
        alarms = self.alarm_manager.get_all_alarms()
        if not alarms:
            QMessageBox.information(self, "提示", "当前没有闹钟可导出。")
            return

        # 生成默认文件名
        default_filename = f"桌面闹钟备份_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"

        filepath, _ = QFileDialog.getSaveFileName(
            self,
            "导出闹钟到文件",
            default_filename, # 默认文件名
            "JSON 文件 (*.json);;所有文件 (*.*)"
        )

        if filepath:
            print(f"准备导出闹钟到文件: {filepath}")
            try:
                exported_count = self.alarm_manager.export_alarms_to_json(filepath)
                if exported_count is not None:
                    QMessageBox.information(self, "导出完成", f"成功导出 {exported_count} 个闹钟到\n{filepath}")
                else:
                    QMessageBox.warning(self, "导出失败", "导出过程中发生错误，请检查日志。")
            except Exception as e:
                print(f"导出闹钟时发生未知错误: {e}")
                QMessageBox.critical(self, "导出错误", f"导出时发生未知错误: {e}")
        else:
            print("用户取消了导出操作。")
        # -------------------------
        # QMessageBox.information(self, "提示", "导出功能尚未实现。") # <-- 旧的占位符

    # --- 闹钟列表右键菜单 ---
    @pyqtSlot(QPoint)
    def show_alarm_context_menu(self, position):
        item = self.alarm_list_widget.itemAt(position)
        if item:
            alarm_id = item.data(Qt.ItemDataRole.UserRole)
            alarm = self.alarm_manager.get_alarm(alarm_id)
            if not alarm: return

            menu = QMenu()
            
            # --- 修改选项 ---
            edit_action = QAction("修改闹钟", self)
            edit_action.triggered.connect(lambda checked=False, item=item: self.load_alarm_for_editing(item))
            menu.addAction(edit_action)

            menu.addSeparator()
            
            # --- 删除选项 ---
            delete_action = QAction("删除闹钟", self)
            delete_action.triggered.connect(lambda: self.remove_selected_alarm()) 
            menu.addAction(delete_action)

            menu.exec(self.alarm_list_widget.mapToGlobal(position))

    def load_alarm_for_editing(self, item: QListWidgetItem):
        alarm_id = item.data(Qt.ItemDataRole.UserRole)
        alarm = self.alarm_manager.get_alarm(alarm_id)
        if alarm:
            self.editing_alarm_id = alarm_id
            
            # 填充数据
            qdt = QDateTime(alarm.alarm_time) if alarm.alarm_time else QDateTime.currentDateTime()
            self.datetime_edit.setDateTime(qdt)
            self.message_edit.setText(alarm.message)
            
            repeat_text = alarm.repeat_rule if alarm.repeat_rule else DEFAULT_REPEAT_RULE_DISPLAY
            repeat_index = self.repeat_combo.findText(repeat_text)
            if repeat_index != -1: self.repeat_combo.setCurrentIndex(repeat_index)
            else: self.repeat_combo.setCurrentIndex(0) # 回退到第一个
            
            category_text = alarm.category if alarm.category else DEFAULT_CATEGORY
            category_index = self.category_combo.findText(category_text)
            if category_index != -1: self.category_combo.setCurrentIndex(category_index)
            else: # 如果分类不存在 (理论上不应发生，因为 manager 会处理), 选择默认
                 default_cat_index = self.category_combo.findText(DEFAULT_CATEGORY)
                 if default_cat_index != -1: self.category_combo.setCurrentIndex(default_cat_index)
                 elif self.category_combo.count() > 0: self.category_combo.setCurrentIndex(0)
                
            # 更新UI状态
            self.add_edit_groupbox.setTitle("编辑闹钟")
            self.save_button.setText("更新闹钟")
            self.cancel_button.setVisible(True)
            print(f"已加载闹钟 {alarm_id} 进行编辑")
        else:
             print(f"错误: 无法加载闹钟 {alarm_id} 进行编辑")
             self.reset_edit_state() # 加载失败则重置
            
    def reset_edit_state_if_needed(self, current: QListWidgetItem, previous: QListWidgetItem):
        # 如果用户点击了列表中的其他项，并且当前正在编辑，则取消编辑状态
        # 但要避免在 load_alarm_for_editing 刚设置完 item 后立即触发
        # 简单的处理：只要列表选中变化就取消编辑（用户需要右键重新加载）
        if self.editing_alarm_id:
             # 检查当前选中的 item 是否是正在编辑的 item
             if current is None or current.data(Qt.ItemDataRole.UserRole) != self.editing_alarm_id:
                  print("列表选择变化，取消编辑状态")
                  self.reset_edit_state()

    @pyqtSlot()
    def reset_edit_state(self):
        """重置编辑状态和UI控件"""
        self.editing_alarm_id = None
        self.add_edit_groupbox.setTitle("添加闹钟")
        self.save_button.setText("添加闹钟")
        self.cancel_button.setVisible(False)
        
        # 重置输入字段为默认值
        self.datetime_edit.setDateTime(QDateTime.currentDateTime().addSecs(60))
        self.message_edit.clear()
        repeat_index = self.repeat_combo.findText(DEFAULT_REPEAT_RULE_DISPLAY)
        if repeat_index != -1: self.repeat_combo.setCurrentIndex(repeat_index)
        default_cat_index = self.category_combo.findText(DEFAULT_CATEGORY)
        if default_cat_index != -1: self.category_combo.setCurrentIndex(default_cat_index)
        
        # 取消列表中的任何潜在视觉高亮（如果添加了的话）
        # self.alarm_list_widget.clearSelection() # 这可能会干扰用户正常选择，暂时不用
        print("编辑状态已重置")

    @pyqtSlot()
    def save_or_update_alarm(self):
        """根据是否存在 editing_alarm_id 来保存或更新闹钟"""
        alarm_time_qdt = self.datetime_edit.dateTime()
        alarm_time_dt = alarm_time_qdt.toPyDateTime()
        message = self.message_edit.text().strip()
        repeat_rule_text = self.repeat_combo.currentText()
        category = self.category_combo.currentText()
        
        # --- 基本校验 ---
        if not message: QMessageBox.warning(self, "提醒", "请输入提醒事项。"); return
        if not alarm_time_dt: QMessageBox.warning(self, "提醒", "无效的时间设置。"); return
        # --- 移除添加时的过期检查，统一在后面处理 --- \
        # if alarm_time_dt <= datetime.now() and not self.editing_alarm_id: \
        #      QMessageBox.warning(self, "提醒", "添加闹钟时，时间必须晚于当前。"); return
           
        # --- 将UI选择映射回存储值 ---
        repeat_rule = repeat_rule_text if repeat_rule_text != DEFAULT_REPEAT_RULE_DISPLAY else None

        if self.editing_alarm_id:
            # --- 更新现有闹钟 ---
            if alarm_time_dt <= datetime.now():
                 # --- 使用 HTML 优化提示信息 --- \
                 warning_html = f"""
                 <p style='font-size: 11pt; color: #E0E0E0;'><b>时间设置无效</b></p>
                 <p style='font-size: 10pt; color: #CCCCCC;'>您设置的时间 (<i>{alarm_time_dt.strftime('%Y-%m-%d %H:%M:%S')}</i>) 已经过去。
                 <br/>闹钟将无法触发。
                 <br/><br/>请选择一个未来的时间后再点击"更新闹钟"。</p>
                 """
                 QMessageBox.warning(self, "提醒 - 时间已过期", warning_html)
                 return
            # -------------------------------\
            
            print(f"尝试更新闹钟: {self.editing_alarm_id}")
            original_alarm = self.alarm_manager.get_alarm(self.editing_alarm_id)
            if not original_alarm: QMessageBox.critical(self, "错误", "无法找到要更新的闹钟！"); self.reset_edit_state(); return
                
            original_alarm.alarm_time = alarm_time_dt
            original_alarm.message = message
            original_alarm.repeat_rule = repeat_rule
            original_alarm.category = category
            original_alarm.enabled = True

            self.alarm_manager.update_alarm(original_alarm)
            print(f"闹钟 {self.editing_alarm_id} 已更新并启用")
            self.reset_edit_state()

        else:
            # --- 添加新闹钟 ---
            if alarm_time_dt <= datetime.now():
                 # --- 使用 HTML 优化提示信息 --- \
                 warning_html = f"""
                 <p style='font-size: 11pt; color: #E0E0E0;'><b>时间设置无效</b></p>
                 <p style='font-size: 10pt; color: #CCCCCC;'>您设置的时间 (<i>{alarm_time_dt.strftime('%Y-%m-%d %H:%M:%S')}</i>) 已经过去。
                 <br/>请选择一个未来的时间。</p>
                 """
                 QMessageBox.warning(self, "提醒 - 时间已过期", warning_html)
                 return
            # -------------------------------\
            print("尝试添加新闹钟")
            new_alarm = Alarm(alarm_time=alarm_time_dt, message=message)
            new_alarm.repeat_rule = repeat_rule
            new_alarm.category = category
            self.alarm_manager.add_alarm(new_alarm)
            self.reset_edit_state()

# ... (if __name__ == '__main__' block remains unchanged) ...
# 保留原来的 if __name__ == '__main__' 块用于单独测试窗口
if __name__ == '__main__':
    # 用于单独测试窗口
    app = QApplication(sys.argv)
    # 需要确保能找到 core 模块
    sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    # 确保 QApplication 在 MainWindow 销毁前不退出，即使没有可见窗口
    app.setQuitOnLastWindowClosed(False) 
    window = MainWindow()
    window.show()
    sys.exit(app.exec())